package org.example.service.impl;

import com.google.common.base.Strings;
import org.example.entity.Service;
import org.example.entity.param.ServiceAddParam;
import org.example.entity.param.ServiceDeleteParam;
import org.example.entity.param.ServiceHeartBeatParam;
import org.example.entity.vo.ServiceVO;
import org.example.service.IRegistryService;
import org.example.util.ExpiringCache;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author sxt
 * @version 1.0
 * @description TODO
 * @date 2023/7/31 22:09
 */
@org.springframework.stereotype.Service
public class RegistryServiceImpl implements IRegistryService {

    @Resource
    private ExpiringCache<String, Service> cache;

    @SuppressWarnings("FieldCanBeLocal")
//    private final long SERVICE_EXPIRED_TIME = 1000 * 60;
    private final long SERVICE_EXPIRED_TIME = 6000;

    @Override
    public boolean registry(ServiceAddParam serviceAddParam) {
        // 注册服务到内存缓存
        String id = UUID.randomUUID().toString();
        Service service = new Service();
        BeanUtils.copyProperties(serviceAddParam, service);
        service.setServiceId(id);
        return cache.put(id, service, SERVICE_EXPIRED_TIME);
    }

    @Override
    public boolean unRegistry(ServiceDeleteParam serviceDeleteParam) {
        String serviceId = serviceDeleteParam.getServiceId();
        if (!Strings.isNullOrEmpty(serviceId)) {
            return cache.remove(serviceId);
        } else {
            String ipAddress = serviceDeleteParam.getIpAddress();
            String port = serviceDeleteParam.getPort();
            if (Strings.isNullOrEmpty(ipAddress) || Strings.isNullOrEmpty(port)) {
                return false;
            }
            Service service = new Service();
            BeanUtils.copyProperties(serviceDeleteParam, service);
            return cache.removeByCondition(service);
        }
    }

    @Override
    public List<ServiceVO> discovery(String name) {
        if (Strings.isNullOrEmpty(name)) {
            List<Service> services = cache.getAll();
            return services.stream().map(service -> {
                ServiceVO serviceVO = new ServiceVO();
                BeanUtils.copyProperties(service, serviceVO);
                return serviceVO;
            }).collect(Collectors.toList());
        }
        return cache.getByValueField("serviceName", name).stream().map(service -> {
            ServiceVO serviceVO = new ServiceVO();
            BeanUtils.copyProperties(service, serviceVO);
            return serviceVO;
        }).collect(Collectors.toList());
    }

    @Override
    public boolean hearBeat(ServiceHeartBeatParam serviceHeartBeatParam) {
        String serviceId = serviceHeartBeatParam.getServiceId();
        if (!Strings.isNullOrEmpty(serviceId)) {
            return cache.refreshExpire(serviceId, SERVICE_EXPIRED_TIME);
        } else {
            String ipAddress = serviceHeartBeatParam.getIpAddress();
            String port = serviceHeartBeatParam.getPort();
            if (Strings.isNullOrEmpty(ipAddress) || Strings.isNullOrEmpty(port)) {
                return false;
            }
            Service service = new Service();
            BeanUtils.copyProperties(serviceHeartBeatParam, service);
            return cache.refreshExpireByCondition(service, SERVICE_EXPIRED_TIME);
        }
    }
}
